package com.ssm.changeunit.console;

import com.ssm.changeunit.ChangeUnitException;
import com.ssm.changeunit.Environment;
import com.ssm.changeunit.command.*;
import com.ssm.changeunit.console.parser.*;
import com.ssm.changeunit.util.LogUtil;
import java.io.File;
import org.apache.log4j.Logger;

/**
 * Console 명령어를 받아 처리하는 클래스 
 * 
 * @author 시리우스
 */
public class ChangeUnitConsole {
    private static final Logger logger = Logger.getLogger(ChangeUnitConsole.class);
    
    public static void main(String[] userCommand) {
        try {
            // 환경 변수 체크
            if( System.getenv("CHANGEUNIT_ROOT") == null )
                throw new ChangeUnitException("CHANGEUNIT_ROOT 환경 변수를 찾을수 없습니다.");
            
            if( System.getenv("CHANGEUNIT_USERID") == null )
                throw new ChangeUnitException("CHANGEUNIT_USERID 환경 변수를 찾을수 없습니다.");
            
            // 커맨드가 없는 경우
            if(userCommand.length == 0) 
                throw new ChangeUnitException("명령어를 찾을 수 없습니다.");
            
            // 커맨드를 일정한 모양으로 변화
            String command =
                    userCommand[0].substring(0, 1).toUpperCase() // 첫 글자를 대문자로
                    + userCommand[0].substring(1, userCommand[0].length()).toLowerCase(); // 나머지 글자는 소문자로

            CommandWorkerOptions commandWorkerOptions = null;

            // Console에 들어온 명령을 parsing
            try {
                // 리플렉션을 사용해 Parser 클래스를 찾아옵니다.
                Class consoleParserClass = Class.forName("com.ssm.changeunit.console.parser." + command + "ConsoleParser");

                // Parser 클래스의 객체를 생성합니다.
                ConsoleParser consoleParser = (ConsoleParser)consoleParserClass.newInstance();

                // Parse 메서드를 호출해 CommandWorkerOptions을 구합니다.
                commandWorkerOptions = consoleParser.parse(userCommand);
            }
            catch(ClassNotFoundException ex) {
                // 클래스를 찾지 못한 경우
                // 즉, 처리할 수 없는 명령어인 경우
                StringBuilder errorMessage = new StringBuilder();
                
                errorMessage.append("잘못된 명령어 입니다.");
                errorMessage.append("명령어: " + userCommand[0]);
                
                throw new ChangeUnitException(errorMessage.toString());
            }
            catch(ConsoleParseException ex) {
                // Console 명령어를 Parsing하지 못한 경우
                throw new ChangeUnitException("Console 명령어를 분석하는데 실패했습니다.", ex);
            }

            try {
                // 리플렉션을 사용해 CommandWorker 클래스를 찾아옵니다.
                Class commandWorkerClass = Class.forName("com.ssm.changeunit.command." + command + "CommandWorker");

                // CommandWorker 객체를 생성합니다.
                CommandWorker commandWorker = (CommandWorker)commandWorkerClass.newInstance();

                // Work 메서드를 수행합니다.
                commandWorker.work(commandWorkerOptions);
            }
            catch(ClassNotFoundException ex) {
                // CommandWorker클래스를 찾지 못한 경우
                StringBuilder errorMessage = new StringBuilder();
                
                errorMessage.append("CommandWorker 클래스를 찾을 수 없습니다.");
                errorMessage.append("명령어: " + userCommand[0]);
                
                throw new ChangeUnitException(errorMessage.toString());
            }
        }
        catch(ChangeUnitException ex) {
            logger.error(LogUtil.stackTraceToString(ex));
        }
        catch(Throwable ex) {
            // 알수 없는 에러가 발생한 경우
            logger.fatal(LogUtil.stackTraceToString(ex));
        }
    }
}
